package battleship;

import java.util.*;

import cwcFramework.CWCFAbstractRobot;

import com.google.wave.api.*;
import com.google.wave.api.event.*;

public class BattleshipRobot extends CWCFAbstractRobot {

	private static final String gadgetURL = "http://cwcf-battleship.appspot.com/gadget/battleship.xml";
	
	public BattleshipRobot() {
		super();
	}
	
	@Override
	protected String getRobotEMail() {
		return "cwcf-battleship@appspot.com";
	}
	
	@Override
	protected String getRobotName() {
		return "Battleship CWCF";
	}

	@Override
	protected String getRobotAvatarUrl() {
		return "http://cwcf-battleship.appspot.com/avatar.png";
	}

	@Override
	protected String getRobotProfilePageUrl() {
		return "http://cwc-framework.googlecode.com";
	}
	
	@Override
	protected String getOAuthKey(boolean usingWaveSandbox) {
		if (usingWaveSandbox){
			return "";
		}else{
			return "";
		}
	}

	@Override
	protected String getOAuthSecret(boolean usingWaveSandbox) {
		if (usingWaveSandbox){
			return "";
		}else{
			return "";
		}
	}

	@Override
	protected String getSecurityToken() {
		return "";
	}

	@Override
	protected String getVerificationToken() {
		return "";
	}
	
	@Override
	public void initializePrivateWaves(Wavelet bufferWave, ArrayList<Wavelet> privateWaves){
		int counter = 0;
		for (Wavelet wave : privateWaves) {
			counter += 1;
			Gadget gadget = new Gadget(gadgetURL);
			wave.getRootBlip().append(gadget);
			gadget.setProperty("participantNr", Integer.toString(counter));
		}
	}
	
	public void onWaveletSelfAdded(WaveletSelfAddedEvent event) {
		// get wave, get participants
		// LOG.info("New on Wavelet Self Added");
		Wavelet bufferWave = event.getWavelet();
		bufferWave.reply("\nHi everybody! Let's play!");
		Participants participants = bufferWave.getParticipants();
		Object[] partArray = participants.toArray();

		// check to see if there are only 2 participants
		if (partArray.length != 3){
			String mess = "\nThis game can only be played by two players";
			mess += "\nPlease add this Battleship Robot to a wave with two participants to play";
			bufferWave.reply(mess);	
		}else{			
			//create playing waves for two participants
			startBinaryCommunication(participants, bufferWave);
		}
	}

	@Override
	public void onGadgetStateChanged(GadgetStateChangedEvent event){
		Wavelet origWave = event.getWavelet();
		// get local gadget
		String localSYou = readLocalGadgetState(origWave, gadgetURL, "syou");
		String localTurn = readLocalGadgetState(origWave, gadgetURL, "turn");

		// get remote gadget
		String remoteSMe = readRemoteGadgetState(getRemoteWaveId(origWave), getRemoteWaveletId(origWave), gadgetURL, "sme");
		String remoteTurn = readRemoteGadgetState(getRemoteWaveId(origWave), getRemoteWaveletId(origWave), gadgetURL, "turn");

		if (localTurn != null && remoteTurn != null){
			if (localTurn.equalsIgnoreCase("waiting") && remoteTurn.equalsIgnoreCase("waiting") ){
				// Update local gadget states
				writeLocalGadgetState(origWave, gadgetURL, "turn", "ready");
				
				// Update remote gadget states
				writeRemoteGadgetState(origWave, getRemoteWaveId(origWave), getRemoteWaveletId(origWave), gadgetURL, "turn", "ready");	
			}else{
				if (localSYou != null && remoteSMe != null ){
					//Retrieve gadget state
					String[] localYou = deserialize(localSYou,",");
					String[] remoteMe = deserialize(remoteSMe,",");

					//Game logic
					Boolean played = false;
					for (int i=0; i < 100; i++) {
						if((localYou[i]).equals("clicked")){
							if(remoteMe[i].equals("boat")){
								localYou[i] = "touched";
								remoteMe[i] = "touched";
							}
							else{
								localYou[i] = "miss";
								remoteMe[i] = "miss";
							}
							played = true;
						}
					}

					if (played) {
						// Update local gadget states
						writeLocalGadgetState(origWave, gadgetURL, "syou", serialize(localYou, ","));

						// Update remote gadget states
						writeRemoteGadgetState(origWave, getRemoteWaveId(origWave), getRemoteWaveletId(origWave), gadgetURL, "sme", serialize(remoteMe, ","));
						writeRemoteGadgetState(origWave, getRemoteWaveId(origWave), getRemoteWaveletId(origWave), gadgetURL, "turn", "mine");
					}
				}
			}
		}
	}

	
	
	private String[] deserialize(String serializedString, String separator){
		//Reconstruct array from "stringified" version (javascript)
		//Note: size (10x10) is hard coded.
		String toDeserialize = serializedString.replace("[", "").replace("]", "");
		String[] a = toDeserialize.split(separator);
		if (a == null || separator == null) {
			return null;
		}
		String[] result = new String[100];

		if (a.length > 0) {
			for (int i=0; i < 100; i++) {
				result[i] = a[i].replace("\"", "");
			}
		}
		return result;
	}

	private String serialize(String[] array, String separator){
		//Reconstruct "stringified" string of the array
		//Note: size (10x10) is hard coded.

		String result ="["; 
		for (int i=0; i < 100; i++){
			result+="\""+array[i]+"\"";
			if (i != 99) result+=separator;
		}
		result.subSequence(0, result.length()-2);
		result+="]";

		return result;
	}

}


